package calbs.socket.analysis;/**
 * Created by zhangqin on 2017/8/2.
 */

import calbs.socket.enu.FrameReqEnum;
import calbs.socket.exception.AnalySocketException;
import calbs.socket.exception.AnalySocketExceptionEmum;
import calbs.socket.pojo.req.*;
import calbs.socket.server.cache.UserCache;
import calbs.socket.tool.Byte2Hex;
import calbs.socket.tool.CHexConver;
import calbs.socket.tool.XorTool;
import io.netty.channel.Channel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static calbs.socket.enu.FrameReqEnum.*;

/**
 * 协议解析工厂
 *
 * @author
 * @create 2017-08-02 11:53
 **/
public final  class AnalysisFactory {
    private static final Logger logger = LoggerFactory.getLogger(AnalysisFactory.class);
    public static ReqData analysis(String message, Channel channel){
        if(!message.toUpperCase().startsWith("7E7D")&&!message.toUpperCase().endsWith("7E7D")){
            if(StringUtils.isBlank(UserCache.get(channel))) {
                throw new AnalySocketException(AnalySocketExceptionEmum.NO_FRAME_NOLGOIN);
            }else{
                throw new AnalySocketException(AnalySocketExceptionEmum.NO_FRAME);
            }
        }
        ReqData reqData =null;
        AnalysisI analysisI = null;
        FrameReqEnum fm = getFrameEnum(message.substring(2*2,2*2+2*1));
        if(fm != DS_LOGIN ){
            if(StringUtils.isBlank(UserCache.get(channel))){
              throw new AnalySocketException(AnalySocketExceptionEmum.NO_LOGIN);
            }
        }


        switch (fm){
            case DS_LOGIN:
                reqData = new ReqData<ReqLoginMsg>() ;
                reqData.setBody(new ReqLoginMsg());
                buildCommonParams(reqData,message);
                analysisI = new LoginAnalysisImp();
                break;
            case CMD_NOP:
                reqData = new ReqData<ReqBaseMsg>();
                reqData.setBody(new ReqBaseMsg()
                );
                buildCommonParams(reqData,message);
                analysisI = new GetPingAnalysisImp();
                return analysisI.analysisMsg(reqData);
            case DS_FINISH:
                reqData =  new ReqData<ReqFinishMsg>();
                reqData.setBody(new ReqFinishMsg());
                buildCommonParams(reqData,message);
                analysisI = new DsFinishAnalysisImp();
                break;
            case DS_GETLINE:
                reqData =  new ReqData<ReqGetAbLineMsg>();
                reqData.setBody(new ReqGetAbLineMsg());
                buildCommonParams(reqData,message);
                analysisI = new GetAbLineAnalysisImp();
                break;
            case DS_POS:
                reqData =  new ReqData<ReqUploadLocationMsg>();
                reqData.setBody(new ReqUploadLocationMsg());
                buildCommonParams(reqData,message);
                analysisI = new UploadLocationAnalysisImp();
                break;
            case DS_ABLINE_UPLOAD:
                reqData = new ReqData<ReqUploadAbLineMsg>();
                reqData.setBody(new ReqUploadAbLineMsg());
                buildCommonParams(reqData,message);
                analysisI = new UploadAblineAnalysisImp();
                break;
            case DS_ALARMCODE:
                reqData = new ReqData<ReqUploadWarningMsg>();
                reqData.setBody(new ReqUploadWarningMsg());
                buildCommonParams(reqData,message);
                analysisI = new UploadWarningAnalysisImp();
                break;
            case DS_UPDATE:
                reqData = new ReqData<ReqGetSoftUpdateVersionMsg>();
                reqData.setBody(new ReqGetSoftUpdateVersionMsg());
                buildCommonParams(reqData,message);
                analysisI = new GetSoftUpdateVersionAnalysisImp();
                break;
                default:
                    throw new AnalySocketException(AnalySocketExceptionEmum.NO_FRAME);
        }
        reqData.setChannel(channel);
        reqData.setDevice(UserCache.get(channel));
        reqData.setOldContent(message);
        return  analysisI.analysisMsg(reqData);
    }

        private static void buildCommonParams(ReqData reqData, String message){
            ReqBaseMsg body = reqData.getBody();
            message = message.substring(2*2);
            body.setFrameNumber(message.substring(0,2*1));
            message= message.substring(2*1);
            body.setFrameNumberSerial(message.substring(0,2*2));
            message= message.substring(2*2);
            body.setFrameContentLength(Integer.parseInt(message.substring(0,2*2),16));
            message= message.substring(2*2);
            body.setVerifyCode(message.substring(0,2*1));
            message= message.substring(2*1);
            body.setContent(message.substring(0,message.length()-2*2));
            logger.info("verify code :"+body.getVerifyCode());
            logger.info("verify code my self :"+ Byte2Hex.Bytes2HexString(new byte[]{XorTool.getXor(CHexConver.hexStr2Bytes(body.getContent()))}));
        }

    public static void main(String[] args) {
        System.out.println(Integer.parseInt("000C",16));
    }
}
